# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: yuxuan

import numpy as np

from coin.support.feed_tool.feed_stats.logic.util import to_book_builder_exchange_symbol


class ArchiveFeedCacheBuilder(object):
  _sub_request = None

  def __init__(self, products, columns, interval_ends):
    self._columns = columns
    self._interval_ends = interval_ends
    self._products = products
    self._data = {column: None for column in self._columns}
    self._timestamp = 0
    self._aggregate_idx = 0
    self._data = dict()
    self._init_data()

  @staticmethod
  def exchange():
    raise NotImplementedError()

  @staticmethod
  def price_types():
    return ['High', 'Low', 'Open', 'Close']

  def _init_data(self):
    for product in self._products:
      for column in self._columns:
        self._data[(product, column)] = {
            value_type: [np.nan for _ in range(len(self._interval_ends))
                        ] for value_type in self.price_types()
        }

  def on_book_reset(self, book_builder_name, book_builder):
    raise NotImplementedError()

  def get_data(self, product, column):
    return self._data[(product, column)]

  def on_feed_impl(self, timestamp, product, map_data):
    assert timestamp >= self._timestamp
    self._timestamp = timestamp
    while self._timestamp > self._interval_ends[self._aggregate_idx]:
      self._aggregate_idx += 1
    for column, a_data in map_data.items():
      key = (product, column)
      data = self._data[key]
      if np.isnan(float(data['High'][self._aggregate_idx])) or \
          a_data > data['High'][self._aggregate_idx]:
        data['High'][self._aggregate_idx] = a_data
      if np.isnan(float(data['Low'][self._aggregate_idx])) or \
          a_data < data['Low'][self._aggregate_idx]:
        data['Low'][self._aggregate_idx] = a_data
      if np.isnan(float(data['Open'][self._aggregate_idx])):
        data['Open'][self._aggregate_idx] = a_data
      data['Close'][self._aggregate_idx] = a_data

  def on_feed(self, book):
    raise NotImplementedError()
